package com.hengtiansoft.lfy.utils;

import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;


import com.hengtiansoft.lfy.LFYApplication;
import com.iflytek.cloud.SpeechConstant;
import com.iflytek.cloud.SpeechError;
import com.iflytek.cloud.SynthesizerListener;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 语音播放
 */
public class Kdxf_TTSPlayer {

   /* private int sampleRateInHz = 16000;
    private int channelConfig = AudioFormat.CHANNEL_IN_MONO;
    private int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
    private int playChannelConfig = AudioFormat.CHANNEL_OUT_MONO;

    private Thread audioTrackThread;
    private int waveDataSize = 0;
    private int playBufSizeInBytes = 0;
    private int maxWaveSec = 60;
    private byte[] allWaveData = new byte[sampleRateInHz * 2 * maxWaveSec]; //采样最大存放2*60秒数据
    private final int PLAYING = 3;
    private final int STOPPLAY = 4;
    private AudioTrack audioTrack;
    Activity activity;*/
    //科大讯飞------------------------------
    private File file;
    private boolean isPlaying = false;
    // 引擎类型
    private String mEngineType = SpeechConstant.TYPE_CLOUD;
    //
    private MediaPlayer mediaPlayer;
    private SynthesizerListener mExternalTtsListener;
    //自定义说话人
    private String cusSpeaker = "";
    private Kdxf_TTSPlayer() {
    }

    private static Kdxf_TTSPlayer mPlayer;
    public static Kdxf_TTSPlayer getInstense() {
        if (mPlayer == null) {
            mPlayer = new Kdxf_TTSPlayer();

        }
        return mPlayer;
    }

    //科大讯飞
    /**
     * 参数设置
     * @param   speed "50"
     * @return
     */
    /*if(!transferType.equals("zh_cn")){
        voicer = "xiaoyan";
    }else{
        voicer="catherine";
    }*/
    private void setParam(String voicer, int speed, String filepath){
        // 清空参数
        LFYApplication.getInstance().mTts.setParameter(SpeechConstant.PARAMS, null);
        // 根据合成引擎设置相应参数
        if(mEngineType.equals(SpeechConstant.TYPE_CLOUD)) {
            LFYApplication.getInstance().mTts.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD);
            // 设置在线合成发音人
            LFYApplication.getInstance().mTts.setParameter(SpeechConstant.VOICE_NAME, voicer);
            //设置合成语速
            LFYApplication.getInstance().mTts.setParameter(SpeechConstant.SPEED, speed+"");
            //设置合成音调
            LFYApplication.getInstance().mTts.setParameter(SpeechConstant.PITCH,"50");
            //设置合成音量
            LFYApplication.getInstance().mTts.setParameter(SpeechConstant.VOLUME,"50");
        }else {
            LFYApplication.getInstance().mTts.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_LOCAL);
            // 设置本地合成发音人 voicer为空，默认通过语记界面指定发音人。
            LFYApplication.getInstance().mTts.setParameter(SpeechConstant.VOICE_NAME, "");
            /**
             * TODO 本地合成不设置语速、音调、音量，默认使用语记设置
             * 开发者如需自定义参数，请参考在线合成参数设置
             */
        }
        //设置播放器音频流类型
        LFYApplication.getInstance().mTts.setParameter(SpeechConstant.STREAM_TYPE,  "0");
        // 设置播放合成音频打断音乐播放，默认为true
        LFYApplication.getInstance().mTts.setParameter(SpeechConstant.KEY_REQUEST_FOCUS, "true");

        // 设置音频保存路径，保存音频格式支持pcm、wav，设置路径为sd卡请注意WRITE_EXTERNAL_STORAGE权限
        // 注：AUDIO_FORMAT参数语记需要更新版本才能生效
        if(!"".equals(filepath)) {
            LFYApplication.getInstance().mTts.setParameter(SpeechConstant.AUDIO_FORMAT, "wav");
             LFYApplication.getInstance().mTts.setParameter(SpeechConstant.TTS_AUDIO_PATH,filepath);
        }
    }

    /**
     * 自定义合成人
     * @param str
     * @param transferType
     * @param filepath
     * @param speaker
     */
    public void TTSPlay(String str, String transferType, String filepath,String speaker){
        playAudio();
        this.cusSpeaker = speaker;
        TTSPlay(str,transferType,filepath);
    }

    public void TTSPlay(String str, String transferType, String filepath) {
        playAudio();
        if (isPlaying) {
            stop();
        }
        String synText = str;
        synText = synText.trim();

        if (synText.length() <= 0)
            return;
        isPlaying = true;
        //-------------科大讯飞---------------------
        String voicer="xiaoyan";
        if("".equals(cusSpeaker)) {
            if (transferType.equals("chen")) {
                if ("f".equals(LFYApplication.getInstance().getSettingSexChoose())) {//女
                    voicer = "catherine";
                } else {
                    voicer = "henry";
                }
            } else {
                Pattern p = Pattern.compile("[\u4e00-\u9fa5]");
                Matcher m = p.matcher(str);
                if (m.find()) {
                    if ("f".equals(LFYApplication.getInstance().getSettingSexChoose())) {//女
                        voicer = "xiaoyan";
                    } else {
                        voicer = "xiaoyu";
                    }
                } else {
                    if ("f".equals(LFYApplication.getInstance().getSettingSexChoose())) {//女
                        voicer = "catherine";
                    } else {
                        voicer = "henry";
                    }

                }
            }
        }else{
            voicer = cusSpeaker;
            cusSpeaker = "";
        }
       float mspeed=LFYApplication.getInstance().getSettingSpeedChoose();
        int speed=50;
        if (mspeed < 0.5)
            mspeed = 0.5f;
        else if (mspeed > 2)
            mspeed = 2;
        speed=(int)mspeed*speed;
        setParam(voicer,speed,filepath);
        LFYApplication.getInstance().mTts.startSpeaking(synText, mTtsListener);
    }

    /**
     * 设置外部合成回调
     * @param listener
     */
    public void setExternalTtsListener(SynthesizerListener listener){
        mExternalTtsListener = listener;
    }


    public void stopTTs(){
        if(LFYApplication.getInstance().mTts !=null) {
            LFYApplication.getInstance().mTts.stopSpeaking();
        }
    }

    /**
     * 合成回调监听。
     */
    private SynthesizerListener mTtsListener = new SynthesizerListener() {

        @Override
        public void onSpeakBegin() {
            // showTip("开始播放");
            if(mExternalTtsListener != null)
                mExternalTtsListener.onSpeakBegin();
        }

        @Override
        public void onSpeakPaused() {
            //  showTip("暂停播放");
            if(mExternalTtsListener != null)
                mExternalTtsListener.onSpeakPaused();
        }

        @Override
        public void onSpeakResumed() {
            // showTip("继续播放");
            if(mExternalTtsListener != null)
                mExternalTtsListener.onSpeakResumed();
        }

        @Override
        public void onBufferProgress(int percent, int beginPos, int endPos,
                                     String info) {
            // 合成进度
          /*  mPercentForBuffering = percent;
            showTip(String.format(getString(R.string.tts_toast_format),
                    mPercentForBuffering, mPercentForPlaying));*/
            if(mExternalTtsListener != null)
                mExternalTtsListener.onBufferProgress(percent,beginPos,endPos,info);
        }

        @Override
        public void onSpeakProgress(int percent, int beginPos, int endPos) {
            // 播放进度
          /*  mPercentForPlaying = percent;
            showTip(String.format(getString(R.string.tts_toast_format),
                    mPercentForBuffering, mPercentForPlaying));*/
            if(mExternalTtsListener != null)
                mExternalTtsListener.onSpeakProgress(percent,beginPos,endPos);
        }

        @Override
        public void onCompleted(SpeechError error) {
            if (error == null) {
                //showTip("播放完成");
                if (isPlaying)
                    stop();
            } else if (error != null) {
                // showTip(error.getPlainDescription(true));
                if (isPlaying)
                    stop();
            }
            if(mExternalTtsListener != null)
                mExternalTtsListener.onCompleted(error);
        }

        @Override
        public void onEvent(int eventType, int arg1, int arg2, Bundle obj) {
            // 以下代码用于获取与云端的会话id，当业务出错时将会话id提供给技术支持人员，可用于查询会话日志，定位出错原因
            // 若使用本地能力，会话id为null
            //	if (SpeechEvent.EVENT_SESSION_ID == eventType) {
            //		String sid = obj.getString(SpeechEvent.KEY_EVENT_SESSION_ID);
            //		Log.d(TAG, "session id =" + sid);
            //	}
            if(mExternalTtsListener != null)
                mExternalTtsListener.onEvent(eventType,arg1,arg2,obj);
        }
    };

    public void TTSPlayOpu_assets(String assetsName, Context context) {
//        Log.i("caijiajun", "wodao");
        if (isPlaying) {
            stop();
        }

            isPlaying = true;
           playAudio();
            if(mediaPlayer==null) {
                mediaPlayer = new MediaPlayer();
                mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {

                    @Override
                    public void onCompletion(MediaPlayer mp) {
                        //播放完成
                        if (isPlaying)
                            stop();
                    }
                });
                mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {

                    @Override
                    public boolean onError(MediaPlayer mp, int what, int extra) {
                        //播放异常
                        if (isPlaying)
                            stop();
                        return false;
                    }
                });
            }
            try {
                mediaPlayer.reset();
                AssetFileDescriptor fileDescriptor=context.getAssets().openFd(assetsName);
                mediaPlayer.setDataSource(fileDescriptor.getFileDescriptor(),
                        fileDescriptor.getStartOffset(),
                        fileDescriptor.getLength());
                mediaPlayer.setAudioStreamType(AudioManager.STREAM_VOICE_CALL);
                mediaPlayer.prepare();
                mediaPlayer.start();
            } catch (IllegalArgumentException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                if (isPlaying)
                    stop();
            } catch (SecurityException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                if (isPlaying)
                    stop();
            } catch (IllegalStateException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                if (isPlaying)
                    stop();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                if (isPlaying)
                    stop();
            }

    }

    public void TTSPlayOpu(String filePath, String transferType) {
//        Log.i("caijiajun", "wodao");
        if (isPlaying) {
            stop();
        }
        if (filePath == null || !((file = new File(filePath)).exists())) {
            TTSPlay("文件出错",transferType,"");
        } else {
            isPlaying = true;
            playAudio();
            if(mediaPlayer==null) {
                mediaPlayer = new MediaPlayer();
                mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {

                    @Override
                    public void onCompletion(MediaPlayer mp) {
                        //播放完成
                        if (isPlaying)
                            stop();
                        if(mExternalTtsListener != null)
                            mExternalTtsListener.onCompleted(null);
                    }
                });
                mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {

                    @Override
                    public boolean onError(MediaPlayer mp, int what, int extra) {
                        //播放异常
                        if (isPlaying)
                            stop();
                        if(mExternalTtsListener != null)
                            mExternalTtsListener.onCompleted(null);
                        return false;
                    }
                });
            }
            try {
                mediaPlayer.reset();
                mediaPlayer.setDataSource(new FileInputStream(filePath).getFD());
                mediaPlayer.setAudioStreamType(AudioManager.STREAM_VOICE_CALL);
                mediaPlayer.prepare();
                mediaPlayer.start();
            } catch (IllegalArgumentException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                if (isPlaying)
                    stop();
            } catch (SecurityException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                if (isPlaying)
                    stop();
            } catch (IllegalStateException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                if (isPlaying)
                    stop();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                if (isPlaying)
                    stop();
            }
        }
    }
    SensorManager mSensorManager;
    AudioManager audioManager;
    Sensor mSensor;
    private void playAudio() {
        audioManager = (AudioManager) LFYApplication.getInstance()
                    .getSystemService(Context.AUDIO_SERVICE);
        if(!LFYApplication.getInstance().getSettingMsgSpeaker()) {
            mSensorManager = (SensorManager) LFYApplication.getInstance().getSystemService(Context.SENSOR_SERVICE);
            mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
            mSensorManager.registerListener(mySensorEventListener, mSensor,
                    SensorManager.SENSOR_DELAY_NORMAL);
        }
       // audioManager.setSpeakerphoneOn(false);

        if(!LFYApplication.getInstance().getSettingMsgSpeaker()) {
            setSpeakerPhoneOn(true);
        }else {
            setSpeakerPhoneOn(false);

        }
    }
    /**
     * 听筒、扬声器切换
     *
     * 注释： 敬那些年踩过的坑和那些网上各种千奇百怪坑比方案！！
     *
     * AudioManager设置声音类型有以下几种类型（调节音量用的是这个）:
     *
     * STREAM_ALARM 警报
     * STREAM_MUSIC 音乐回放即媒体音量
     * STREAM_NOTIFICATION 窗口顶部状态栏Notification,
     * STREAM_RING 铃声
     * STREAM_SYSTEM 系统
     * STREAM_VOICE_CALL 通话
     * STREAM_DTMF 双音多频,不是很明白什么东西
     *
     * ------------------------------------------
     *
     * AudioManager设置声音模式有以下几个模式（切换听筒和扬声器时setMode用的是这个）
     *
     * MODE_NORMAL 正常模式，即在没有铃音与电话的情况
     * MODE_RINGTONE 铃响模式
     * MODE_IN_CALL 接通电话模式 5.0以下
     * MODE_IN_COMMUNICATION 通话模式 5.0及其以上
     *
     * @param on
     */
    private void setSpeakerPhoneOn(boolean on) {

        if (on) {
            audioManager.setSpeakerphoneOn(true);
            audioManager.setMode(AudioManager.MODE_NORMAL);
            //设置音量，解决有些机型切换后没声音或者声音突然变大的问题
            audioManager.setStreamVolume(AudioManager.STREAM_MUSIC,
                    audioManager.getStreamVolume(AudioManager.STREAM_MUSIC), AudioManager.FX_KEY_CLICK);

        } else {

            audioManager.setSpeakerphoneOn(false);

            //5.0以上
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
                audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
                //设置音量，解决有些机型切换后没声音或者声音突然变大的问题
                audioManager.setStreamVolume(AudioManager.STREAM_VOICE_CALL,
                        audioManager.getStreamMaxVolume(AudioManager.STREAM_VOICE_CALL), AudioManager.FX_KEY_CLICK);

            } else {
                audioManager.setMode(AudioManager.MODE_IN_CALL);
                audioManager.setStreamVolume(AudioManager.STREAM_VOICE_CALL,
                        audioManager.getStreamMaxVolume(AudioManager.STREAM_VOICE_CALL), AudioManager.FX_KEY_CLICK);
            }

        }

    }
    SensorEventListener mySensorEventListener=new SensorEventListener(){
        @Override
        public void onSensorChanged(SensorEvent event) {
            if(audioManager==null){
                return;
            }
            if(mSensor==null){
                return;
            }
            float range = event.values[0];
            Log.i("supeng",range+","+mSensor.getMaximumRange());
            if (range >= mSensor.getMaximumRange()) {
                if(!LFYApplication.getInstance().getSettingMsgSpeaker()) {
                    setSpeakerPhoneOn(true);
                }
            } else {
                if(!LFYApplication.getInstance().getSettingMsgSpeaker()) {
                    setSpeakerPhoneOn(false);
                }
            }
        }

        @Override
        public void onAccuracyChanged(Sensor sensor, int i) {

        }
    };
    private StopListener stopListener;
    public interface StopListener{
        public void stop();
    }
    public void setStopListener(StopListener stopListener){
        this.stopListener=stopListener;
    }
    public void stop() {
        if (!isPlaying) {
            return;
        }
        isPlaying = false;
        if(stopListener!=null){
            stopListener.stop();
        }
        if(mSensorManager!=null){
            mSensorManager.unregisterListener(mySensorEventListener);
        }
        if (mediaPlayer != null) {
            mediaPlayer.stop();
        }

        if(LFYApplication.getInstance().mTts !=null){
            LFYApplication.getInstance().mTts.stopSpeaking();
        }
    }
    public void reStop() {
    /*    if (mediaPlayer != null) {
            mediaPlayer.stop();
        }

        if(LFYApplication.getInstance().mTts !=null){
            LFYApplication.getInstance().mTts.stopSpeaking();
        }*/
    }
}
